from dataclasses import dataclass
import pandas as pd
from .window import *
from .datagrad import Data2Grade
from collections import defaultdict
import itertools
import math

class UpgradeFeature:
    
    def __init__(self, applist:[{},{},...], data:pd.DataFrame, cutwin:TimeWindow = TimeWindow([3, 7, 15, 30, 60, 90, 180, 50000])):
        """
        app_list: 用户app原始安装列表数据
        data: 外部数据关联数据表，如竞品列表
        cutwin: TimeWindow类，用于生成时间窗口，拆分原始数据
        """
        self.app_list = pd.DataFrame(applist)
        self.data = data
        self.cutwin = cutwin
        self.get_meta()
        
    def get_meta(self):
        self.meta = {
            'grade_feature':'app更新次数',
            'loanupgrade_feature':'竞品app更新次数'
        }
        self.func_map = {
            'grade_feature':self.upgrade_feature,
            'loanupgrade_feature':self.loanupgrade_feature
        }
        
    def __call__(self,fuc_list:list):
        dfs = []
        for name, al in self.cutwin.iter(self.app_list):
            for func in fuc_list:
                feature_dict = self.func_map[func](data=al,loan_data=self.deal_data(al, self.data))
                if feature_dict:
                    features_new = [{f"{key}_{name}":feature_dict[key]} for key in feature_dict]
                    dfs.extend(features_new)
            
        return self.cutwin.merge_dfs(dfs)
    
    def upgrade_feature(self,data:pd.DataFrame,**kwargs):
        feature_dict = defaultdict(int)
        if not data.empty:
            for idx, row in data.iterrows():
                if row['inst_time'] != row['updt_time']:
                    feature_dict[self.join_str(['ugd', 'cnt'])] += 1
        else:
            feature_dict[self.join_str(['ugd', 'cnt'])] = 0
        return feature_dict
    
    def loanupgrade_feature(self,loan_data:pd.DataFrame,**kwargs):
        feature_dict = defaultdict(int)
        if not loan_data.empty:
            for idx, row in loan_data.iterrows():
                if row['inst_time'] != row['updt_time']:
                    feature_dict[self.join_str(['loanugd', 'cnt'])] += 1
        else:
            feature_dict[self.join_str(['loanugd', 'cnt'])] = 0
        return feature_dict
            
    def join_str(self,tag_list:list):
        return '_'.join(tag_list)
    
    def deal_data(self, applist:pd.DataFrame, data:pd.DataFrame):
        loan_list = data['package_name'].tolist()
        return applist[applist['package'].isin(loan_list)]